package pers.xiaojun.boot.module.system.convert;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import pers.xiaojun.boot.common.util.CollectionUtils;
import pers.xiaojun.boot.module.system.controller.user.vo.user.UserRespVO;
import pers.xiaojun.boot.module.system.controller.user.vo.user.UserSimpleRespVO;
import pers.xiaojun.boot.module.system.dao.entity.dept.DeptDO;
import pers.xiaojun.boot.module.system.dao.entity.user.AdminUserDO;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户转换器
 *
 * @author xiaojun
 * @since 2025-11-02
 */
@Mapper
public interface UserConvert {

    UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);

    /**
     * 转换 AdminUserDO 和 DeptDO -> UserRespVO
     *
     * @param user 用户信息
     * @param dept 部门信息
     * @return UserRespVO
     */
    default UserRespVO toUserRespVO(AdminUserDO user, DeptDO dept, List<Long> postIds) {
        UserRespVO userVO = BeanUtil.toBean(user, UserRespVO.class);
        if (dept != null) {
            userVO.setDeptName(dept.getName());
        }
        if (CollUtil.isNotEmpty(postIds)) {
            userVO.setPostIds(CollUtil.newHashSet(postIds));
        }
        return userVO;
    }

    /**
     * 转 List<UserRespVO>
     *
     * @param users 用户列表
     * @param depts 部门列表
     * @return List<UserRespVO>
     */
    default List<UserRespVO> toUserVOList(List<AdminUserDO> users, List<DeptDO> depts) {
        return convertUserAndDept(users, depts,
                user -> BeanUtil.toBean(user, UserRespVO.class),
                (userVO, dept) -> userVO.setDeptName(dept.getName())
        );
    }

    /**
     * 转 List<UserSimpleRespVO>
     *
     * @param users 用户列表
     * @param depts 部门列表
     * @return List<UserSimpleRespVO>
     */
    default List<UserSimpleRespVO> toSimpleUserList(List<AdminUserDO> users, List<DeptDO> depts) {
        return convertUserAndDept(users, depts,
                user -> BeanUtil.toBean(user, UserSimpleRespVO.class),
                (userVO, dept) -> userVO.setDeptName(dept.getName())
        );
    }

    /**
     * 转换 AdminUserDO 列表为指定数据类型的列表
     *
     * @param users  用户列表
     * @param depts  部门列表
     * @param mapper 转换函数
     * @param setter 属性配置函数
     * @param <T>    目标类型
     * @return 转换后的列表
     */
    default <T> List<T> convertUserAndDept(List<AdminUserDO> users, List<DeptDO> depts, Function<AdminUserDO, T> mapper, BiConsumer<T, DeptDO> setter) {
        Map<Long, DeptDO> deptMap = Optional.ofNullable(depts)
                .orElse(Collections.emptyList())
                .stream()
                .collect(Collectors.toMap(DeptDO::getId, Function.identity(), (a, b) -> a));

        return CollectionUtils.convertList(users, user -> {
            T t = mapper.apply(user);
            DeptDO dept = deptMap.get(user.getDeptId());
            if (dept != null) {
                setter.accept(t, dept);
            }
            return t;
        });
    }

}
